#pragma once

#include <string>
#include <mutex>
#include <vector>
#include <iostream>
#include <memory>
#include <functional>
#include <unordered_map>
#include <type_traits>
#include <iterator>
#include <algorithm>
#include <cmath>
#include <limits>
#include <iomanip>

#include <glog/logging.h>

// #include "api.h"
#include "error.h"

namespace Pbrt{
    // Inline Functions
    inline float Lerp(
        float t,
        float v1,
        float v2
    )
    {
        return (1 - t) * v1 + t * v2;
    }

    // Global Forward Declarations
    #include "../Scene/scene.h"
    class Scene;
    // ----------
    class Integrator;
    class SamplerIntegrator;
    #include "../Integrator/integrator.h"
    // ----------
    template<typename T> class Vector2;
    template<typename T> class Vector3;
    template<typename T> class Point2;
    template<typename T> class Point3;
    template<typename T> class Normal3;
    template<typename T> class Ray;
    template<typename T> class RayDifferential;
    template<typename T> class Bounds2;
    template<typename T> class Bounds3;
    #include "geometry.h"
    // ----------
    class Camera;
    

    struct Options{
        Options(){
            cropWindow[0][0] = 0;
            cropWindow[0][1] = 1;
            cropWindow[1][0] = 0;
            cropWindow[1][1] = 1;
        };

        int nThreads = 0;
        bool quickRender = false;
        bool quiet = false;
        bool cat = false;
        bool toPly = false;
        std::string imageFile;
        float cropWindow[2][2];
    };

    extern Options PbrtOptions;




};